package com.auto.autoapp.network

import android.util.Log
import com.google.gson.JsonParseException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import retrofit2.HttpException
import java.io.IOException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

/**
 * 基础 Repository 类
 * 提供统一的网络请求处理方法
 */
open class BaseRepository {
    
    companion object {
        private const val TAG = "BaseRepository"
    }
    
    /**
     * 执行网络请求并返回 Flow
     * @param apiCall 网络请求的挂起函数
     * @return Flow<NetworkResult<T>>
     */
    protected fun <T> executeRequest(
        apiCall: suspend () -> T
    ): Flow<NetworkResult<T>> = flow {
        // 发送加载中状态
        emit(NetworkResult.Loading)
        
        try {
            // 执行网络请求
            val response = apiCall()
            // 发送成功状态
            emit(NetworkResult.Success(response))
        } catch (e: Exception) {
            // 处理异常并发送错误状态
            val error = handleException(e)
            emit(NetworkResult.Error(error.message ?: "未知错误", error.code))
            Log.e(TAG, "API request failed", e)
        }
    }.flowOn(Dispatchers.IO) // 在 IO 线程执行
    
    /**
     * 执行网络请求并返回 Flow（带业务逻辑判断）
     * 适用于有统一响应格式的 API
     * @param apiCall 网络请求的挂起函数
     * @param transform 数据转换函数，用于从响应中提取实际数据
     * @return Flow<NetworkResult<T>>
     */
    protected fun <R, T> executeRequestWithTransform(
        apiCall: suspend () -> R,
        transform: (R) -> T
    ): Flow<NetworkResult<T>> = flow {
        emit(NetworkResult.Loading)
        
        try {
            val response = apiCall()
            val data = transform(response)
            emit(NetworkResult.Success(data))
        } catch (e: Exception) {
            val error = handleException(e)
            emit(NetworkResult.Error(error.message ?: "未知错误", error.code))
            Log.e(TAG, "API request failed", e)
        }
    }.flowOn(Dispatchers.IO)
    
    /**
     * 处理异常
     * @param exception 异常对象
     * @return ApiException
     */
    private fun handleException(exception: Exception): ApiException {
        return when (exception) {
            // HTTP 异常
            is HttpException -> {
                val code = exception.code()
                val message = when (code) {
                    400 -> "请求参数错误"
                    401 -> "未授权，请重新登录"
                    403 -> "禁止访问"
                    404 -> "请求的资源不存在"
                    408 -> "请求超时"
                    500 -> "服务器内部错误"
                    502 -> "网关错误"
                    503 -> "服务不可用"
                    504 -> "网关超时"
                    else -> "服务器错误: $code"
                }
                ApiException.ServerException(message, code)
            }
            
            // 网络连接异常
            is UnknownHostException -> {
                ApiException.NetworkException("网络连接失败，请检查网络设置")
            }
            
            // 超时异常
            is SocketTimeoutException -> {
                ApiException.TimeoutException("连接超时，请稍后重试")
            }
            
            // IO 异常
            is IOException -> {
                ApiException.NetworkException("网络错误: ${exception.message}")
            }
            
            // JSON 解析异常
            is JsonParseException -> {
                ApiException.ParseException("数据解析失败")
            }
            
            // API 业务异常
            is ApiException -> {
                exception
            }
            
            // 其他未知异常
            else -> {
                ApiException.UnknownException("未知错误: ${exception.message}")
            }
        }
    }
}


